﻿Namespace Flows
    Public Class MetisFlowList
        Inherits MetisSortedEntityList(Of IMetisFlowNode)

        Private _MetisCore As MetisCore

        Private _Parent As MetisFlow

        ''' <summary>Creates a new MetisFlowList and loads all Flows from the DB.</summary>
        ''' <param name="MetisCore">Reference to the central management object of Metis that manages the access to the DB.</param>
        Sub New(ByVal MetisCore As MetisCore)
            _MetisCore = MetisCore

            Dim OraReader As OracleDataReader
            Dim OraCmd As OracleCommand
            OraCmd = New OracleCommand("SELECT flow_id, flow_name, annotation, NVL(parent_flow_fk,-1) " &
                                       "FROM dam_flows " &
                                       "CONNECT BY PRIOR flow_id=parent_flow_fk START WITH parent_flow_fk IS NULL " &
                                       "ORDER BY level, flow_name", _MetisCore.Connection)

            OraReader = OraCmd.ExecuteReader
            Do While OraReader.Read
                Dim tmpParenNamespace As MetisFlow = Find(OraReader.GetInt32(3))
                Dim tmpAnnotation As String = If(OraReader.IsDBNull(2), "", OraReader.GetString(2))

                Dim tmpNamespace As New MetisFlow(_MetisCore, OraReader.GetInt32(0), OraReader.GetString(1), tmpParenNamespace, tmpAnnotation)

                If tmpParenNamespace IsNot Nothing Then
                    tmpParenNamespace.Children.Add(tmpNamespace)
                Else
                    Me.Add(tmpNamespace)
                End If
            Loop
            OraReader.Close()
        End Sub

        ''' <summary>Creates a new FlowList</summary>
        ''' <param name="MetisCore">Reference to the central management object of Metis that manages the access to the DB.</param>
        ''' <param name="Parent">Reference to its parent Flow</param>
        ''' <remarks>No further action (load from DB) will be taken.</remarks>
        Sub New(ByVal MetisCore As Core.MetisCore, ByVal Parent As MetisFlow)
            _MetisCore = MetisCore
            _Parent = Parent
        End Sub

        Private Sub HandleListItemPropChange(ByVal sender As Object, ByVal e As System.ComponentModel.ListChangedEventArgs) Handles Me.ListChanged
            If e.ListChangedType = System.ComponentModel.ListChangedType.ItemChanged AndAlso _
               e.PropertyDescriptor IsNot Nothing AndAlso e.PropertyDescriptor.Name = "Name" Then
                SetItem(e.NewIndex, Me(e.NewIndex))
            End If
        End Sub

        ''' <summary>Inserts a new Flow into the List.</summary>
        ''' <param name="index">The Index where the new item should be added.</param>
        ''' <param name="item">The Flow to add.</param>
        ''' <remarks>The Flow will be added at the position of its alphabetical order (by its name) within the list, no matter what index was specified</remarks>
        ''' <exception cref="Core.Exceptions.DublicateNameException">Raised when the name of the inserted Flow is already used in the list.</exception>
        Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As IMetisFlowNode)
            MyBase.InsertItem(index, item)
            If TypeOf item Is MetisFlow AndAlso
               ((_Parent IsNot Nothing AndAlso Not _Parent.Equals(DirectCast(item, MetisFlow).Parent)) OrElse _Parent Is Nothing) Then DirectCast(item, MetisFlow).Parent = _Parent
        End Sub

        Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As IMetisFlowNode)
            MyBase.SetItem(index, item)
            If TypeOf item Is MetisFlow AndAlso
               ((_Parent IsNot Nothing AndAlso Not _Parent.Equals(DirectCast(item, MetisFlow).Parent)) OrElse _Parent Is Nothing) Then DirectCast(item, MetisFlow).Parent = _Parent
        End Sub

        Public ReadOnly Property Parent() As MetisFlow
            Get
                Return _Parent
            End Get
        End Property

        Public Overrides Sub Reload()

        End Sub

        Public Overrides Function Find(ByVal ID As Integer) As IMetisFlowNode
            For Each Item As IMetisFlowNode In Me
                If Item.ID = ID Then
                    Return Item
                ElseIf TypeOf Item Is MetisFlow Then
                    Dim tmpFlow As MetisFlow = DirectCast(Item, MetisFlow).Children.Find(ID)
                    If tmpFlow IsNot Nothing Then Return tmpFlow
                End If
            Next
            Return Nothing
        End Function
    End Class
End Namespace

